import os
import time
import json
from typing import Optional

import requests


class TelegramNotifier:
    """Simple Telegram Bot API notifier using sendMessage.

    Requires environment variables:
      - TELEGRAM_BOT_TOKEN
      - TELEGRAM_CHAT_ID (can be user/channel/group id)
    """

    def __init__(self, bot_token: Optional[str] = None, chat_id: Optional[str] = None) -> None:
        self.bot_token = bot_token or os.getenv("TELEGRAM_BOT_TOKEN", "").strip()
        self.chat_id = chat_id or os.getenv("TELEGRAM_CHAT_ID", "").strip()
        if not self.bot_token or not self.chat_id:
            raise RuntimeError(
                "TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID must be set via env or parameters"
            )
        self.base_url = f"https://api.telegram.org/bot{self.bot_token}"

    def send_message(self, text: str, parse_mode: Optional[str] = None, disable_web_page_preview: bool = True) -> None:
        url = f"{self.base_url}/sendMessage"
        payload = {
            "chat_id": self.chat_id,
            "text": text,
            "disable_web_page_preview": disable_web_page_preview,
        }
        if parse_mode:
            payload["parse_mode"] = parse_mode

        backoff_seconds = 1.0
        for attempt in range(5):
            try:
                response = requests.post(url, json=payload, timeout=10)
                if response.status_code == 429:
                    # Rate limited
                    retry_after = response.json().get("parameters", {}).get("retry_after", backoff_seconds)
                    time.sleep(float(retry_after))
                    continue
                response.raise_for_status()
                data = response.json()
                if not data.get("ok", False):
                    raise RuntimeError(f"Telegram API error: {json.dumps(data, ensure_ascii=False)}")
                return
            except Exception:
                if attempt == 4:
                    raise
                time.sleep(backoff_seconds)
                backoff_seconds *= 2


